﻿#ifndef XQRCODE_H
#define XQRCODE_H
#include<QString>
#include<QList>
#include<QPixmap>
//二维码生成
class XQRCode
{
public:
	XQRCode();
	XQRCode(const QString& text);
	~XQRCode()=default;
	//获取二维码Pixmap对象
	static QPixmap to_Pixmap(const QString& text, int width = 10, const QColor& backColor = Qt::black, const QColor& color = Qt::white);
	//获取二维码Pixmap对象黑色背景
	static QPixmap to_Pixmap_black(const QString& text, int width = 10);
	//获取二维码Pixmap对象白色背景
	static QPixmap to_Pixmap_white(const QString& text, int width = 10);
public:
	//获取二维码数组的大小(边长)
	int data_size()const;
	//获取二维码数据
	QVector<QVector<unsigned char>> data()const;
	//转QPixmap  一个点的宽度,背景颜色,颜色
	QPixmap to_Pixmap(int width = 10, const QColor& backColor = Qt::black, const QColor& color = Qt::white);
	//获取黑色背景二维码
	QPixmap to_Pixmap_black(int width=10);
	//获取白色背景二维码
	QPixmap to_Pixmap_white(int width=10);
	//编码数据转控制台输出 01数据
	void data_outCmd()const;
public:
	//编码数据
	bool qrcode_encode(const QString& text);
protected://数据计算
	//编码数据//返回比特长度
	int set_encode_data(const QByteArray& data);
	//设置数据码字流
	int set_data_code(int index, int data, int size);
	//选择合适的版本
	int get_encode_version(int bits_count);
	//设置补齐码（Padding Bytes）
	//如果数据没有达到我们最大的bits数的限制，我们还要加一些补齐码，
	//就是重复下面的两个bytes：11101100(0xEC),00010001(0x11)
	int set_padding_byte(int version, int data_bits_count);
	//设置纠错码
	int set_code_word(int version, int data_code_count);
	//格式化数据
	void format_qrcode_data(int version, int code_word_count);
	//设置功能性图案
	void set_function_patterns(int version);
	//设置定位图案（Position Detection Pattern）
	//3个大回字，是定位图案，用于标记二维码的矩形大小。
	void set_postion_pattern(int x, int y);
	//设置定位图案的分隔线(Separators for Postion Detection Patterns)
	void set_separator_pattern(void);
	//设置对齐图案（Alignment Patterns ）
	//是除了3个大回字，较小的回字。在Version >= 2上的二维码需要，同样是为了定位用的。
	void set_alignment_pattern(int x, int y);
	//设置标准线（Timing Patterns）
	//黑白相间的参考线，也是用于定位的。
	void set_timing_pattern(void);
	//设置版本信息（Version Information ）
	//在Version >= 7以上，需要预留两块3 x 6的区域存放一些版本信息。
	void set_version_info(int version);
	//设置码字图形，把数据码和纠错码的各个codewords交替放在一起。
	//规则如下：
	//对于数据码：把每个块的第一个codewords先拿出来按顺度排列好，
	//然后再取第一块的第二个，如此类推。如：上述示例中的Data Codewords如下
	void set_code_word_pattern(int code_word_count);
	//从8种掩码中选择最佳掩码图形
	void get_masking_pattern(int* mask);
	//设置掩码图案(Mask Pattern)
	//避免出现大量黑块或白块，有8种图案可选择，进行XOR操作
	void set_masking_pattern(int masking);
	//设置格式化信息（Format Information）
	//是一个15个bits的信息，包含纠错等级(2bit)和遮蔽图形信息(3bit)
	void set_format_info(int masking);
	//图案评审，计算禁区大小
	//出现连续黑块或白块越多则禁区越大
	int get_penalty_count(void);
protected:
	QVector<unsigned char> m_data_code;
	QVector<unsigned char> m_rsec_code;
	QVector<unsigned char> m_code_word;
	int m_qrcode_size=0;
	QVector<QVector<unsigned char>> m_qrcode_data;
};
#endif